package co.gov.medellin.ssti.sub.model.dao.impl;

import java.math.BigDecimal;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.springframework.dao.IncorrectResultSizeDataAccessException;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcDaoSupport;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import org.springframework.jdbc.support.GeneratedKeyHolder;

import co.gov.medellin.ssti.sub.common.util.Utility;
import co.gov.medellin.ssti.sub.model.dao.BeneficiarioDAO;
import co.gov.medellin.ssti.sub.model.dao.exception.DAOException;
import co.gov.medellin.ssti.sub.model.vo.BeneficiarioVO;
import co.gov.medellin.ssti.sub.model.vo.BeneficioVO;

public class BeneficiarioDAOImpl2 extends NamedParameterJdbcDaoSupport
		implements BeneficiarioDAO {

	private static final String SELECT_GRUPO_FAMILIAR_SISBEN = "SELECT TIPODOC, DOCUMENT, NOM1, NOM2, TO_CHAR(FECHANTO,'DD/MM/YY') FECHANTO, "
			+ " APE1, APE2, SEXO, TELES, DIRECC, HOGAR, "
			+ " ZONA, COMUNA, ESTCIVIL, CARNET, PARENTES,"
			+ " PUNTAJE, FICHA FROM TCS_BEN_SISBEN3_NEW_2012 WHERE (FICHA, HOGAR) IN (SELECT ficha , hogar FROM TCS_BEN_SISBEN3_NEW_2012 WHERE tipodoc = :tipodoc AND document = :document ) "
			+ " ORDER BY parentes ";

	private static final String UPDATE_TCS_BEN_BENEFICIARIO = "UPDATE TCS_BEN_BENEFICIARIO SET TIPO_DOCUMENTO = :TIPO_DOCUMENTO, "
			+ " NUMERO_DOCUMENTO = :NUMERO_DOCUMENTO, PRIMER_NOMBRE = UPPER(:PRIMER_NOMBRE), "
			+ " SEGUNDO_NOMBRE = UPPER(:SEGUNDO_NOMBRE), PRIMER_APELLIDO = UPPER(:PRIMER_APELLIDO), "
			+ " SEGUNDO_APELLIDO = UPPER(:SEGUNDO_APELLIDO), VFL_CODIGO_COMUNA = :VFL_CODIGO_COMUNA, "
			+ " FECHA_NACIMIENTO = TO_DATE(:FECHA_NACIMIENTO,'dd/mm/rrrr'), SEXO = :SEXO, "
			+ " TELEFONO = :TELEFONO, DIRECCION_DESCRIPTIVA = :DIRECCION_DESCRIPTIVA, "
			+ " DIRECCION_ENCASILLADA = :DIRECCION_ENCASILLADA, VFL_CODIGO_BARRIO = :VFL_CODIGO_BARRIO, "
			+ " VFL_CODIGO_ZONA = :VFL_CODIGO_ZONA, LOCALIZACION_COBAMA = :LOCALIZACION_COBAMA, "
			+ " CAMPO_A1 = null , CORREO_ELECTRONICO = :CORREO_ELECTRONICO, "
			+ " ETNIA = :ETNIA, USUARIO_MODIFICA = :USUARIO_MODIFICA, TERMINAL_MODIFICA = :TERMINAL_MODIFICA, "
			+ " FECHA_MODIFICA = TO_DATE(:FECHA_MODIFICA,'dd/mm/rrrr'), "
			+ " HECHO_VICTIMIZANTE = :HECHO_VICTIMIZANTE "
			+ " WHERE CODIGO = :CODIGO ";

	private static final String FIND_GF = "SELECT ben.codigo CODIGOBENE, ben.numero_documento, ben.PRIMER_NOMBRE, "
			+ " ben.SEGUNDO_NOMBRE,ben.PRIMER_APELLIDO, ben.SEGUNDO_APELLIDO, "
			+ " gf.nombre Nombre_Grupo, vflex.DESCRIPCION PARENTESCO, "
			+ " cabeza.CODIGO COD_CABEZA, cabeza.PRIMER_NOMBRE||' '||cabeza.SEGUNDO_NOMBRE||' '||cabeza.PRIMER_APELLIDO"
			+ " ||' '||cabeza.SEGUNDO_APELLIDO NOMBRE_CABEZA, cabeza.NUMERO_DOCUMENTO DOC_CABEZA "
			+ " FROM tcs_ben_beneficiario ben, tcs_ben_grupo_familiar gf, "
			+ " tcs_ben_benef_grupo_familiar bgf, paoyer.tcs_valor_flexible vflex, "
			+ " tcs_ben_beneficiario cabeza "
			+ " WHERE vflex.CODIGO = bgf.VFL_CODIGO_PARENTESCO "
			+ " AND ben.codigo = bgf.ben_codigo AND gf.codigo = bgf.gf_codigo "
			+ " AND ben.CAMPO_A1 IS NULL AND cabeza.CODIGO = gf.BEN_CODIGO "
			+ " AND bgf.gf_codigo = :gf_codigo ";

	private static final String INSERT_BENEFICIARIO = "INSERT INTO TCS_BEN_BENEFICIARIO"
			+ "(CODIGO, NUMERO_DOCUMENTO, TIPO_DOCUMENTO, PRIMER_NOMBRE,SEGUNDO_NOMBRE, PRIMER_APELLIDO, "
			+ " SEGUNDO_APELLIDO, VFL_CODIGO_COMUNA, FECHA_NACIMIENTO, SEXO, TELEFONO, DIRECCION_DESCRIPTIVA, "
			+ " DIRECCION_ENCASILLADA, LOCALIZACION_COBAMA, CAMPO_A1, VFL_CODIGO_BARRIO, VFL_CODIGO_ZONA, CORREO_ELECTRONICO, ETNIA, "
			+ " usuario_crea,terminal_crea, fecha_crea,usuario_modifica,terminal_modifica,fecha_modifica, HECHO_VICTIMIZANTE ) "
			+ " VALUES ( SCS_BEN_BEN.NextVal, :NUMERO_DOCUMENTO, :TIPO_DOCUMENTO, UPPER(:PRIMER_NOMBRE),UPPER(:SEGUNDO_NOMBRE), "
			+ " UPPER(:PRIMER_APELLIDO), UPPER(:SEGUNDO_APELLIDO), :VFL_CODIGO_COMUNA, TO_DATE(:FECHA_NACIMIENTO,'dd/mm/rrrr'), "
			+ " :SEXO, :TELEFONO, :DIRECCION_DESCRIPTIVA, :DIRECCION_ENCASILLADA, :LOCALIZACION_COBAMA, null, :VFL_CODIGO_BARRIO, "
			+ " :VFL_CODIGO_ZONA, :CORREO_ELECTRONICO, :ETNIA, :usuario_crea, :terminal_crea, TO_DATE(:fecha_crea,'dd/mm/rrrr'), "
			+ " :usuario_modifica, :terminal_modifica, TO_DATE(:fecha_modifica,'dd/mm/rrrr'), :HECHO_VICTIMIZANTE)";

	private static final String FIND_BENEFICIOS_BY_CODBEN = "SELECT * FROM VCS_BENEFICIOS_OTORGADOS WHERE CODBEN = :CODBEN";

	private static final String FIND_ULTIMOS_BENEFICIOS = " SELECT bo.*, fcs_ben_getCountValor(bo.CODSUBPROG, bo.CODBEN) ValorBen "
			+ " FROM VCS_BENEFICIOS_OTORGADOS bo "
			+ " WHERE CODBOT in (select max(bot.CODIGO) codigo "
			+ "                FROM tcs_ben_beneficio_otorgado bot "
			+ "                WHERE TO_DATE(bot.FECHA_BENEFICIO,'dd/mm/rrrr') <= TO_DATE(sysdate,'dd/mm/rrrr') "
			+ "                AND bot.BEN_CODIGO = :BEN_CODIGO "
			+ "                GROUP BY bot.SBPR_CODIGO)";

	private static final String IS_BENEFICIARIO_ASIGNADO = "SELECT CODIGO "
			+ " FROM TCS_BEN_BENEF_GRUPO_FAMILIAR WHERE BEN_CODIGO = :BEN_CODIGO AND GF_CODIGO = :GF_CODIGO";

	private static final String SELECT_ALL_SISBEN = "SELECT * FROM TCS_BEN_SISBEN3_NEW_2012 WHERE 1 = 1 ";

	private static final String SELECT_ALL_VCS_BEN_OTOR_BY_CODBEN_CODSUBPROG = "SELECT * FROM VCS_BENEFICIOS_OTORGADOS WHERE CODBEN = :CODBEN AND CODSUBPROG = :CODSUBPROG";

	private static final String SELECT_BEN_CODIGO = "SELECT BEN_CODIGO FROM TCS_BEN_BENEFICIO_OTORGADO WHERE codigo = :codigo ";

	private static final String SELECT_EDAD_BENEFICIARIO_BY_CODIGO = "SELECT TRUNC((SYSDATE-fecha_nacimiento)/365) EDAD FROM TCS_BEN_BENEFICIARIO WHERE CODIGO = :CODIGO ";

	private static final String SELECT_MAX_CODIGO = "SELECT MAX(codigo) codigo FROM TCS_BEN_BENEFICIARIO";

	public Collection<BeneficiarioVO> findBeneficiarioMEL(
			BeneficiarioVO criteria) {
		Map<String, Object> namedParameters = new HashMap<String, Object>();

		StringBuffer strQuery = new StringBuffer(
				"SELECT * FROM VCS_BEN_CAMPOS_MEL WHERE 'a'='a' ");

		if (criteria.getTipoDocumento() != null
				&& !criteria.getTipoDocumento().equalsIgnoreCase("")) {
			strQuery.append(" AND TIPODOCUMENTO = :TIPODOCUMENTO ");
			namedParameters.put("TIPODOCUMENTO", criteria.getTipoDocumento());
		}
		if (criteria.getNumeroDocumento() != null
				&& !criteria.getNumeroDocumento().equalsIgnoreCase("")) {
			strQuery.append(" AND NUMERODOCUMENTO = :NUMERODOCUMENTO ");
			namedParameters.put("NUMERODOCUMENTO", criteria
					.getNumeroDocumento().trim());
		}
		if (criteria.getNombre1() != null
				&& !criteria.getNombre1().equalsIgnoreCase("")) {
			strQuery.append(" AND NOMBRE1 = UPPER(:NOMBRE1) ");
			namedParameters.put("NOMBRE1", criteria.getNombre1().trim());
		}
		if (criteria.getNombre2() != null
				&& !criteria.getNombre2().equalsIgnoreCase("")) {
			strQuery.append(" AND NOMBRE2 = UPPER(:NOMBRE2) ");
			namedParameters.put("NOMBRE2", criteria.getNombre2().trim());
		}
		if (criteria.getPrimerApellido() != null
				&& !criteria.getPrimerApellido().equalsIgnoreCase("")) {
			strQuery.append(" AND APELLIDO1 = UPPER(:APELLIDO1) ");
			namedParameters.put("APELLIDO1", criteria.getPrimerApellido()
					.trim());
		}
		if (criteria.getSegundoApellido() != null
				&& !criteria.getSegundoApellido().equalsIgnoreCase("")) {
			strQuery.append(" AND APELLIDO2 = UPPER(:APELLIDO2) ");
			namedParameters.put("APELLIDO2", criteria.getSegundoApellido()
					.trim());
		}
		if (criteria.getFechaNacimiento() != null
				&& !criteria.getFechaNacimiento().equalsIgnoreCase("")) {
			strQuery.append(" AND FECHANACIMIENTO = :FECHANACIMIENTO ");
			namedParameters.put("FECHANACIMIENTO", criteria
					.getFechaNacimiento().trim());
		}

		List<BeneficiarioVO> beneficiarios = getNamedParameterJdbcTemplate()
				.query(strQuery.toString(), namedParameters,
						new RowMapper<BeneficiarioVO>() {
							public BeneficiarioVO mapRow(ResultSet rs,
									int rowNum) throws SQLException {
								BeneficiarioVO vo = new BeneficiarioVO();
								vo.setNumeroDocumento(rs
										.getString("NUMERODOCUMENTO"));
								vo.setTipoDocumento(rs
										.getString("TIPODOCUMENTO"));
								vo.setNombre1(rs.getString("NOMBRE1"));
								vo.setPrimerApellido(rs.getString("APELLIDO1"));
								vo.setNombre2(rs.getString("NOMBRE2"));
								vo.setSegundoApellido(rs.getString("APELLIDO2"));
								vo.setFechaNacimiento(rs
										.getString("FECHANACIMIENTO"));
								vo.setSexo(rs.getString("SEXO"));
								vo.setDirDescriptiva(rs.getString("direccion"));
								return vo;
							}
						});

		return beneficiarios;
	}

	public Collection<BeneficiarioVO> findBeneficiarioSisben(
			BeneficiarioVO criteria) {
		Map<String, Object> namedParameters = new HashMap<String, Object>();

		if (criteria == null) {
			throw new IllegalArgumentException(
					"El parametro BeneficiarioVO no puede ser null.");
		}

		StringBuffer stb = new StringBuffer(SELECT_ALL_SISBEN);

		if (criteria.getNombre1() != null
				&& !"".equalsIgnoreCase(criteria.getNombre1())) {
			stb.append("AND UPPER(NOM1) = UPPER(:NOM1) ");
			namedParameters.put("NOM1", criteria.getNombre1());
		}
		if (criteria.getNombre2() != null
				&& !"".equalsIgnoreCase(criteria.getNombre2())) {
			stb.append("AND UPPER(NOM2) = UPPER(:NOM2) ");
			namedParameters.put("NOM2", criteria.getNombre2());
		}
		if (criteria.getPrimerApellido() != null
				&& !"".equalsIgnoreCase(criteria.getPrimerApellido())) {
			stb.append("AND UPPER(APE1) = UPPER(:APE1) ");
			namedParameters.put("APE1", criteria.getPrimerApellido());
		}
		if (criteria.getSegundoApellido() != null
				&& !"".equalsIgnoreCase(criteria.getSegundoApellido())) {
			stb.append("AND UPPER(APE2) = UPPER(:APE2) ");
			namedParameters.put("APE2", criteria.getSegundoApellido());
		}
		if (criteria.getTipoDocumento() != null
				&& !"".equalsIgnoreCase(criteria.getTipoDocumento())) {
			stb.append("AND TIPODOC = :TIPODOC ");
			namedParameters.put("TIPODOC", criteria.getTipoDocumento());
		}
		if (criteria.getNumeroDocumento() != null
				&& !"".equalsIgnoreCase(criteria.getNumeroDocumento())) {
			stb.append("AND DOCUMENT = :DOCUMENT ");
			namedParameters.put("DOCUMENT", criteria.getNumeroDocumento());
		}
		if (criteria.getFechaNacimiento() != null
				&& !"".equalsIgnoreCase(criteria.getFechaNacimiento())) {
			stb.append("AND to_date(FECHANTO,'dd/mm/rrrr') = TO_DATE(:FECHANTO,'dd/mm/rrrr') ");
			namedParameters.put("FECHANTO", criteria.getFechaNacimiento());
		}

		Collection<BeneficiarioVO> usuarios = getNamedParameterJdbcTemplate()
				.query(stb.toString(), namedParameters,
						new RowMapper<BeneficiarioVO>() {
							public BeneficiarioVO mapRow(ResultSet rs,
									int rowNum) throws SQLException {
								BeneficiarioVO vo = new BeneficiarioVO();
								vo.setNombre1(rs.getString("NOM1"));
								vo.setNombre2(rs.getString("NOM2"));
								vo.setPrimerApellido(rs.getString("APE1"));
								vo.setSegundoApellido(rs.getString("APE2"));
								vo.setTipoDocumento(rs.getString("TIPODOC"));
								vo.setNumeroDocumento(rs.getString("DOCUMENT"));
								vo.setTelefono(rs.getString("TELES"));
								vo.setSexo(rs.getString("SEXO"));
								vo.setFechaNacimientoDate(rs
										.getDate("FECHANTO"));
								// FORMATEA LA FECHA EN EL ESTILO DD/MM/YYYY
								SimpleDateFormat formatter = new SimpleDateFormat(
										"dd/MM/yyyy");
								String sdate = formatter.format(vo
										.getFechaNacimientoDate());
								vo.setFechaNacimiento(sdate);
								vo.setDirDescriptiva(rs.getString("DIRECC"));
								// beneficiarioVO.setMail(resultSet.getString("DIRECC"));
								Utility.formatSisben(vo);
								return vo;
							}
						});

		return usuarios;
	}

	public Collection<BeneficiarioVO> findGrupoFamiliarSisben(String tipoDoc,
			String numDoc) {
		Map<String, Object> namedParameters = new HashMap<String, Object>();

		// tipodoc = "1" (cedula)
		namedParameters.put("tipodoc", "1");
		namedParameters.put("document", numDoc);

		List<BeneficiarioVO> familia = getNamedParameterJdbcTemplate().query(
				SELECT_GRUPO_FAMILIAR_SISBEN, namedParameters,
				new RowMapper<BeneficiarioVO>() {
					public BeneficiarioVO mapRow(ResultSet rs, int rowNum)
							throws SQLException {
						BeneficiarioVO vo = new BeneficiarioVO();
						vo.setNumeroDocumento(rs.getString("DOCUMENT"));
						// test fsr
						vo.setTipoDocumento(Utility
								.deformatSisbenDocumentToSubDocument(rs
										.getString("TIPODOC")));
						vo.setNombre1(rs.getString("NOM1"));
						vo.setPrimerApellido(rs.getString("APE1"));
						vo.setNombre2(rs.getString("NOM2"));
						vo.setSegundoApellido(rs.getString("APE2"));
						vo.setFechaNacimiento(rs.getString("FECHANTO"));
						vo.setSexo(rs.getString("SEXO"));
						vo.setParentesco(rs.getString("PARENTES"));
						vo.setGrupoFamiliar(rs.getString("FICHA"));
						vo.setHogar(rs.getString("HOGAR"));
						// Formatea el parentesco
						Utility.formatSisbenParentesco(vo);
						return vo;
					}
				});
		return familia;
	}

	public Collection<BeneficiarioVO> findBeneficiarioByCriteria(
			BeneficiarioVO criteria, String strOrigen) {
		Map<String, Object> namedParameters = new HashMap<String, Object>();

		StringBuilder query = new StringBuilder();
		query.append("SELECT bene.CODIGO CODIGOBENE, bene.NUMERO_DOCUMENTO,  bene.TIPO_DOCUMENTO,");
		query.append("UPPER(bene.PRIMER_NOMBRE) PRIMER_NOMBRE, UPPER(bene.PRIMER_APELLIDO) PRIMER_APELLIDO,");
		query.append("UPPER(bene.SEGUNDO_NOMBRE) SEGUNDO_NOMBRE, UPPER(bene.SEGUNDO_APELLIDO) SEGUNDO_APELLIDO,");
		query.append("TO_CHAR(bene.FECHA_NACIMIENTO,'dd/mm/rrrr') FECHA_NACIMIENTO , bene.SEXO,");
		query.append("bene.TELEFONO, bene.DIRECCION_DESCRIPTIVA,  bene.DIRECCION_ENCASILLADA,");
		query.append("bene.LOCALIZACION_COBAMA,  bgf.GF_CODIGO GF, gf.NOMBRE NOMBRE_GF,");
		query.append("vflexComuna.CODIGO COMUNA, vflexZona.CODIGO COD_ZONA,  vflexZona.DESCRIPCION DESC_ZONA, ");
		query.append("vflexBarrio.CODIGO COD_BARRIO,  vflexBarrio.DESCRIPCION DESC_BARRIO, ");
		query.append("bene.ETNIA, bene.CORREO_ELECTRONICO mail, bene.HECHO_VICTIMIZANTE HECHO_VICTIMIZANTE ");
		query.append("FROM TCS_BEN_BENEFICIARIO bene ");
		query.append("LEFT OUTER JOIN paoyer.TCS_VALOR_FLEXIBLE vflexComuna ");
		query.append("ON vflexComuna.CODIGO = bene.VFL_CODIGO_COMUNA ");
		query.append("LEFT OUTER JOIN ");
		query.append("TCS_BEN_BENEF_GRUPO_FAMILIAR bgf ");
		query.append("ON bgf.BEN_CODIGO = bene.CODIGO ");
		query.append("LEFT OUTER JOIN TCS_BEN_GRUPO_FAMILIAR gf ");
		query.append("ON gf.CODIGO = bgf.GF_CODIGO ");
		query.append("LEFT OUTER JOIN paoyer.TCS_VALOR_FLEXIBLE vflexZona ");
		query.append("ON vflexZona.CODIGO = bene.VFL_CODIGO_ZONA ");
		query.append("LEFT OUTER JOIN paoyer.TCS_VALOR_FLEXIBLE vflexBarrio ");
		query.append("ON vflexBarrio.CODIGO = bene.VFL_CODIGO_BARRIO ");
		query.append("WHERE 1 = 1 ");

		if (!strOrigen.equals("ingresarBeneficiario")) {
			query.append("AND bene.CAMPO_A1 IS NULL ");
		}
		if (criteria.getCode() != null) {
			query.append("AND bene.CODIGO = :CODIGO ");
			namedParameters.put("CODIGO", criteria.getCode());
		}
		if (!(criteria.getNumeroDocumento().trim()).equalsIgnoreCase("")) {
			query.append("AND bene.NUMERO_DOCUMENTO = :NUMERO_DOCUMENTO ");
			namedParameters.put("NUMERO_DOCUMENTO", criteria
					.getNumeroDocumento().trim());
		}
		if (!criteria.getTipoDocumento().equalsIgnoreCase("")) {
			query.append("AND bene.TIPO_DOCUMENTO = :TIPO_DOCUMENTO ");
			namedParameters.put("TIPO_DOCUMENTO", criteria.getTipoDocumento());
		}
		if (!(criteria.getNombre1().trim()).equalsIgnoreCase("")) {
			query.append("AND UPPER(bene.PRIMER_NOMBRE) = UPPER(:PRIMER_NOMBRE) ");
			namedParameters.put("PRIMER_NOMBRE", criteria.getNombre1().trim());
		}
		if (criteria.getNombre2() != null
				&& !(criteria.getNombre2()).trim().equalsIgnoreCase("")) {
			query.append("AND UPPER(bene.SEGUNDO_NOMBRE) = UPPER(:SEGUNDO_NOMBRE) ");
			namedParameters.put("SEGUNDO_NOMBRE", criteria.getNombre2().trim());
		}
		if (!criteria.getPrimerApellido().equalsIgnoreCase("")) {
			query.append("AND UPPER(primer_apellido) = UPPER(:primer_apellido) ");
			namedParameters.put("primer_apellido", criteria.getPrimerApellido()
					.trim());
		}
		if (criteria.getSegundoApellido() != null
				&& !(criteria.getSegundoApellido()).trim().equalsIgnoreCase("")) {
			query.append("AND UPPER(segundo_apellido) = UPPER(:segundo_apellido) ");
			namedParameters.put("segundo_apellido", criteria
					.getSegundoApellido().trim());
		}
		if (criteria.getFechaNacimiento() != null) {
			if (!(criteria.getFechaNacimiento().trim()).equalsIgnoreCase("")) {
				query.append("AND TO_DATE(FECHA_NACIMIENTO,'dd/mm/rrrr') = TO_DATE(:FECHA_NACIMIENTO,'dd/mm/rrrr') ");
				namedParameters.put("FECHA_NACIMIENTO",
						criteria.getFechaNacimiento());
			}
		}
		query.append(" AND rownum <= 100 ORDER BY bene.NUMERO_DOCUMENTO");

		List<BeneficiarioVO> beneficiarios = getNamedParameterJdbcTemplate()
				.query(query.toString(), namedParameters,
						new RowMapper<BeneficiarioVO>() {
							public BeneficiarioVO mapRow(ResultSet rs,
									int rowNum) throws SQLException {
								BeneficiarioVO vo = new BeneficiarioVO();
								vo.setCode(new Long(rs.getLong("CODIGOBENE")));
								vo.setNumeroDocumento(rs
										.getString("NUMERO_DOCUMENTO"));
								vo.setTipoDocumento(rs
										.getString("TIPO_DOCUMENTO"));
								vo.setNombre1(rs.getString("PRIMER_NOMBRE"));
								vo.setPrimerApellido(rs
										.getString("PRIMER_APELLIDO"));
								vo.setNombre2(rs.getString("SEGUNDO_NOMBRE"));
								vo.setSegundoApellido(rs
										.getString("SEGUNDO_APELLIDO"));
								vo.setVflComuna(rs.getString("COMUNA"));
								vo.setFechaNacimiento(rs
										.getString("FECHA_NACIMIENTO"));
								vo.setSexo(rs.getString("SEXO"));
								vo.setTelefono(rs.getString("TELEFONO"));
								vo.setDirDescriptiva(rs
										.getString("DIRECCION_DESCRIPTIVA"));
								vo.setDirEncasillada(rs
										.getString("DIRECCION_ENCASILLADA"));
								vo.setCodeZona(rs.getString("COD_ZONA"));
								vo.setDescZona(rs.getString("DESC_ZONA"));
								vo.setCodeBarrio(rs.getString("COD_BARRIO"));
								vo.setDescBarrio(rs.getString("DESC_BARRIO"));
								vo.setCobama(rs
										.getString("LOCALIZACION_COBAMA"));
								vo.setGrupoFamiliarCode(rs.getLong("GF"));
								vo.setGrupoFamiliar(rs.getString("NOMBRE_GF"));
								vo.setPoseeBeneficios(findPoseeBeneficios(new Long(
										rs.getLong("CODIGOBENE"))));
								vo.setMail(rs.getString("MAIL"));
								vo.setEtnia(rs.getString("ETNIA"));
								vo.setHechoVictimizante(rs
										.getString("HECHO_VICTIMIZANTE"));
								return vo;
							}
						});
		return beneficiarios;
	}

	public Collection<BeneficiarioVO> findBeneficiarioByCriteria(
			BeneficiarioVO criteria, String strOrigen, Long codePrograma,
			Long codeSubprograma) {
		Map<String, Object> namedParameters = new HashMap<String, Object>();

		StringBuffer query = new StringBuffer(
				"SELECT DISTINCT(bene.CODIGO) CODIGOBENE, bene.NUMERO_DOCUMENTO, "
						+ " decode(bene.tipo_documento, 'C', 'Cedula de ciudadania', 'E', \n"
						+ "		'Cedula de extranjeria', 'N', 'Nit', 'P', 'Pasaporte', 'R', 'Registro civil', \n"
						+ "		'T', 'Tarjeta de identidad', 'O', 'Otro', 'I', 'NIP', 'U', 'NUIP', 'S', 'NISE',\n"
						+ "		'Cabildo', bene.tipo_documento) TIPO_DOCUMENTO, "
						+ " UPPER(bene.PRIMER_NOMBRE) PRIMER_NOMBRE, UPPER(bene.PRIMER_APELLIDO) PRIMER_APELLIDO, "
						+ " UPPER(bene.SEGUNDO_NOMBRE) SEGUNDO_NOMBRE, UPPER(bene.SEGUNDO_APELLIDO) SEGUNDO_APELLIDO, "
						+ " TO_CHAR(bene.FECHA_NACIMIENTO,'dd/mm/rrrr') FECHA_NACIMIENTO , bene.SEXO, "
						+ " bene.TELEFONO, bene.DIRECCION_DESCRIPTIVA, "
						+ " bene.DIRECCION_ENCASILLADA, "
						+ " bene.LOCALIZACION_COBAMA, "
						+ " bgf.GF_CODIGO GF, gf.NOMBRE NOMBRE_GF, "
						+ " vflexComuna.CODIGO COMUNA, vflexZona.CODIGO COD_ZONA, "
						+ " vflexZona.DESCRIPCION DESC_ZONA, vflexBarrio.CODIGO COD_BARRIO, "
						+ " vflexBarrio.DESCRIPCION DESC_BARRIO, bene.ETNIA, bene.CORREO_ELECTRONICO mail, FCS_BEN_GET_NUMERO_BENEFICIOS(bene.CODIGO) CANTIDADBENEFICIOS "
						+ " FROM TCS_BEN_BENEFICIARIO bene,paoyer.TCS_VALOR_FLEXIBLE vflexComuna, "
						+ " TCS_BEN_BENEF_GRUPO_FAMILIAR bgf, TCS_BEN_GRUPO_FAMILIAR gf, "
						+ " paoyer.TCS_VALOR_FLEXIBLE vflexZona, paoyer.TCS_VALOR_FLEXIBLE vflexBarrio ");

		if (codePrograma != null) {
			query.append(" , TCS_BEN_BENEFICIO_OTORGADO bot, TCS_BEN_SUBPROGRAMA sub, TCS_BEN_PROGRAMA pro "
					+ " WHERE vflexComuna.CODIGO (+)= bene.VFL_CODIGO_COMUNA "
					+ " AND vflexZona.CODIGO (+)= bene.VFL_CODIGO_ZONA  "
					+ " AND vflexBarrio.CODIGO (+) = bene.VFL_CODIGO_BARRIO "
					+ " AND bgf.BEN_CODIGO (+)= bene.CODIGO "
					+ " AND gf.CODIGO (+)= bgf.GF_CODIGO "
					+ " AND bot.SBPR_CODIGO = sub.CODIGO "
					+ " AND pro.CODIGO = sub.PRG_CODIGO "
					+ " AND bene.CODIGO = bot.BEN_CODIGO "
					+ " AND pro.CODIGO = :pro.CODIGO ");
			namedParameters.put("pro.CODIGO", codePrograma);
			Object codsubpro = (Object) codeSubprograma;
			if (codsubpro != null) {
				if (!codeSubprograma.equals("nulo")) {
					query.append("AND sub.CODIGO = :sub.CODIGO ");
					namedParameters.put("sub.CODIGO", codeSubprograma);
				}
			}
		} else {
			query.append("WHERE vflexComuna.CODIGO (+)= bene.VFL_CODIGO_COMUNA "
					+ " AND vflexZona.CODIGO (+)= bene.VFL_CODIGO_ZONA  "
					+ " AND vflexBarrio.CODIGO (+) = bene.VFL_CODIGO_BARRIO "
					+ " AND bgf.BEN_CODIGO (+)= bene.CODIGO "
					+ " AND gf.CODIGO (+)= bgf.GF_CODIGO ");
		}

		if (!strOrigen.equals("ingresarBeneficiario")) {
			query.append(" AND bene.CAMPO_A1 IS NULL ");
		}
		if (criteria.getCode() != null) {
			query.append(" AND bene.CODIGO = :CODIGO ");
			namedParameters.put("CODIGO", criteria.getCode());
		}
		if (!criteria.getNumeroDocumento().equalsIgnoreCase("")) {
			query.append(" AND bene.NUMERO_DOCUMENTO = :NUMERO_DOCUMENTO ");
			namedParameters.put("NUMERO_DOCUMENTO", criteria
					.getNumeroDocumento().trim());
		}
		if (!criteria.getTipoDocumento().equals("nulo")) {
			query.append(" AND bene.TIPO_DOCUMENTO = :TIPO_DOCUMENTO ");
			namedParameters.put("TIPO_DOCUMENTO", criteria.getTipoDocumento());
		}
		if (!criteria.getNombre1().equalsIgnoreCase("")) {
			query.append(" AND UPPER(bene.PRIMER_NOMBRE) LIKE UPPER(:PRIMER_NOMBRE) ");
			namedParameters.put("PRIMER_NOMBRE", "%"
					+ criteria.getNombre1().trim() + "%");
		}
		if (!criteria.getNombre2().equalsIgnoreCase("")) {
			query.append("AND UPPER(bene.SEGUNDO_NOMBRE) LIKE UPPER(:SEGUNDO_NOMBRE) ");
			namedParameters.put("SEGUNDO_NOMBRE", "%"
					+ criteria.getNombre2().trim() + "%");
		}
		if (!criteria.getPrimerApellido().equalsIgnoreCase("")) {
			query.append("AND UPPER(primer_apellido) like UPPER(:primer_apellido) ");
			namedParameters.put("primer_apellido", "%"
					+ criteria.getPrimerApellido().trim() + "%");
		}
		if (!criteria.getSegundoApellido().equalsIgnoreCase("")) {
			query.append("AND UPPER(segundo_apellido) like UPPER(:segundo_apellido) ");
			namedParameters.put("segundo_apellido", "%"
					+ criteria.getSegundoApellido().trim() + "%");
		}
		query.append(" AND rownum <= 5000 ORDER BY bene.NUMERO_DOCUMENTO");

		List<BeneficiarioVO> beneficiarios = getNamedParameterJdbcTemplate()
				.query(query.toString(), namedParameters,
						new RowMapper<BeneficiarioVO>() {
							public BeneficiarioVO mapRow(ResultSet rs,
									int rowNum) throws SQLException {
								BeneficiarioVO vo = new BeneficiarioVO();
								vo.setCode(rs.getLong("CODIGOBENE"));
								vo.setNumeroDocumento(rs
										.getString("NUMERO_DOCUMENTO"));
								vo.setTipoDocumento(rs
										.getString("TIPO_DOCUMENTO"));
								vo.setNombre1(rs.getString("PRIMER_NOMBRE"));
								vo.setPrimerApellido(rs
										.getString("PRIMER_APELLIDO"));
								vo.setNombre2(rs.getString("SEGUNDO_NOMBRE"));
								vo.setSegundoApellido(rs
										.getString("SEGUNDO_APELLIDO"));
								vo.setVflComuna(rs.getString("COMUNA"));
								vo.setFechaNacimiento(rs
										.getString("FECHA_NACIMIENTO"));
								vo.setSexo(rs.getString("SEXO"));
								vo.setTelefono(rs.getString("TELEFONO"));
								vo.setDirDescriptiva(rs
										.getString("DIRECCION_DESCRIPTIVA"));
								vo.setDirEncasillada(rs
										.getString("DIRECCION_ENCASILLADA"));
								vo.setCodeZona(rs.getString("COD_ZONA"));
								vo.setDescZona(rs.getString("DESC_ZONA"));
								vo.setCodeBarrio(rs.getString("COD_BARRIO"));
								vo.setDescBarrio(rs.getString("DESC_BARRIO"));
								vo.setCobama(rs
										.getString("LOCALIZACION_COBAMA"));
								vo.setGrupoFamiliarCode(rs.getLong("GF"));
								vo.setGrupoFamiliar(rs.getString("NOMBRE_GF"));
								// bene.setPoseeBeneficios(getNumberBeneficios(new
								// Long(rst.getLong(
								// "CODIGOBENE"))));
								vo.setPoseeBeneficios(rs
										.getString("CANTIDADBENEFICIOS"));
								vo.setMail(rs.getString("MAIL"));
								vo.setEtnia(rs.getString("ETNIA"));
								return vo;
							}
						});

		Collection<BeneficiarioVO> beneTemp = new LinkedList<BeneficiarioVO>();
		BeneficiarioVO bene;
		if (criteria.getPoseeBeneficios().equalsIgnoreCase("Si")) {
			List<BeneficiarioVO> benefi = beneficiarios;
			Long desde = null;
			Long hasta = null;
			Long cantidadBeneficios;

			if (!criteria.getDesdeBOT().equals("")) {
				desde = new Long(criteria.getDesdeBOT());
			}
			if (!criteria.getHastaBOT().equals("")) {
				hasta = new Long(criteria.getHastaBOT());
			}

			for (int i = 0; i < beneficiarios.size(); i++) {
				bene = benefi.get(i);
				if (bene.getPoseeBeneficios().equals("0")) {
					beneTemp.add(bene);
				} else if (desde != null && hasta != null) {
					cantidadBeneficios = new Long(bene.getPoseeBeneficios());
					if (cantidadBeneficios.longValue() < desde.longValue()
							|| cantidadBeneficios.longValue() > hasta
									.longValue()) {
						beneTemp.add(bene);
					}
				} else if (desde != null && hasta == null) {
					cantidadBeneficios = new Long(bene.getPoseeBeneficios());
					if (cantidadBeneficios.longValue() < desde.longValue()) {
						beneTemp.add(bene);
					}
				} else if (desde == null && hasta != null) {
					cantidadBeneficios = new Long(bene.getPoseeBeneficios());
					if (cantidadBeneficios.longValue() > hasta.longValue()) {
						beneTemp.add(bene);
					}
				}
			}
			beneficiarios.removeAll(beneTemp);
		} else if (criteria.getPoseeBeneficios().equalsIgnoreCase("No")) {
			List<BeneficiarioVO> benefi = beneficiarios;
			for (int i = 0; i < beneficiarios.size(); i++) {
				bene = (BeneficiarioVO) benefi.get(i);
				Long cantidadBeneficios = new Long(bene.getPoseeBeneficios());
				if (cantidadBeneficios.longValue() > 0) {
					beneTemp.add(bene);
				}
			}
			beneficiarios.removeAll(beneTemp);
		}
		return beneficiarios;
	}

	public int update(BeneficiarioVO criteria) {
		Map<String, Object> namedParamters = new HashMap<String, Object>();

		// revisar si el numero_documento ya existe.
		String strNumeroDocumento = criteria.getNumeroDocumento().toString();
		if (strNumeroDocumento != null) {
			strNumeroDocumento = strNumeroDocumento.trim();
			String strSQL = "SELECT COUNT(NUMERO_DOCUMENTO) "
					+ " FROM TCS_BEN_BENEFICIARIO "
					+ " WHERE TIPO_DOCUMENTO = :TIPO_DOCUMENTO AND NUMERO_DOCUMENTO = :NUMERO_DOCUMENTO AND CODIGO <> :CODIGO ";
			namedParamters.put("TIPO_DOCUMENTO", criteria.getTipoDocumento());
			namedParamters.put("NUMERO_DOCUMENTO", strNumeroDocumento);
			namedParamters.put("CODIGO", criteria.getCode());

			int ret = getNamedParameterJdbcTemplate().queryForObject(strSQL,
					namedParamters, Integer.class);
			if (ret > 0) {
				return -1;
			}
		}

		// reusar
		namedParamters.clear();

		String strNombre1 = criteria.getNombre1();
		if (criteria.getNombre1() != null) {
			strNombre1 = criteria.getNombre1().trim();
		}
		String strNombre2 = criteria.getNombre2();
		if (criteria.getNombre2() != null) {
			strNombre2 = criteria.getNombre2().trim();
		}
		String primerApellido = criteria.getPrimerApellido();
		if (criteria.getPrimerApellido() != null) {
			primerApellido = criteria.getPrimerApellido().trim();
		}
		String segundoApellido = criteria.getSegundoApellido();
		if (criteria.getSegundoApellido() != null) {
			segundoApellido = criteria.getSegundoApellido().trim();
		}

		namedParamters.put("TIPO_DOCUMENTO", criteria.getTipoDocumento());
		namedParamters.put("NUMERO_DOCUMENTO", strNumeroDocumento);
		namedParamters.put("PRIMER_NOMBRE", strNombre1);
		namedParamters.put("SEGUNDO_NOMBRE", strNombre2);
		namedParamters.put("PRIMER_APELLIDO", primerApellido);
		namedParamters.put("SEGUNDO_APELLIDO", segundoApellido);
		namedParamters.put("VFL_CODIGO_COMUNA", criteria.getVflComuna());
		namedParamters.put("FECHA_NACIMIENTO", criteria.getFechaNacimiento());
		namedParamters.put("SEXO", criteria.getSexo());
		namedParamters.put("TELEFONO", criteria.getTelefono());
		namedParamters.put("DIRECCION_DESCRIPTIVA",
				criteria.getDirDescriptiva());
		namedParamters.put("DIRECCION_ENCASILLADA",
				criteria.getDirEncasillada());
		namedParamters.put("VFL_CODIGO_BARRIO", criteria.getCodeBarrio());
		namedParamters.put("VFL_CODIGO_ZONA", criteria.getCodeZona());
		namedParamters.put("LOCALIZACION_COBAMA", criteria.getCobama());
		namedParamters.put("CORREO_ELECTRONICO", criteria.getMail());
		namedParamters.put("ETNIA", criteria.getEtnia());
		namedParamters.put("USUARIO_MODIFICA", criteria.getUpdateUser());
		namedParamters.put("TERMINAL_MODIFICA", criteria.getUpdateTerminal());
		namedParamters.put("FECHA_MODIFICA", criteria.getUpdateDate());
		namedParamters.put("CODIGO", criteria.getCode());

		namedParamters.put("HECHO_VICTIMIZANTE",
				criteria.getHechoVictimizante());

		return getNamedParameterJdbcTemplate().update(
				UPDATE_TCS_BEN_BENEFICIARIO, namedParamters);
	}

	public Collection<BeneficiarioVO> findCabezasGrupoFamiliar(
			BeneficiarioVO criteria) {
		Map<String, Object> namedParameters = new HashMap<String, Object>();

		StringBuffer query = new StringBuffer(
				"SELECT GF.BEN_CODIGO COD_CABEZA, BEN.TIPO_DOCUMENTO, "
						+ " BEN.NUMERO_DOCUMENTO,BEN.PRIMER_NOMBRE, BEN.SEGUNDO_NOMBRE, "
						+ " BEN.PRIMER_APELLIDO, BEN.SEGUNDO_APELLIDO, "
						+ " GF.CODIGO COD_GF, GF.NOMBRE NOM_GF "
						+ " FROM TCS_BEN_GRUPO_FAMILIAR GF, "
						+ " TCS_BEN_BENEFICIARIO BEN "
						+ " WHERE GF.BEN_CODIGO = BEN.CODIGO ");

		if (!criteria.getNumeroDocumento().equalsIgnoreCase("")) {
			query.append(" AND BEN.NUMERO_DOCUMENTO = :NUMERO_DOCUMENTO ");
			namedParameters.put("NUMERO_DOCUMENTO",
					criteria.getNumeroDocumento());
		}
		if (!criteria.getNombre1().equalsIgnoreCase("")) {
			query.append(" AND UPPER(BEN.PRIMER_NOMBRE) LIKE UPPER(:PRIMER_NOMBRE) ");
			namedParameters.put("PRIMER_NOMBRE", "%" + criteria.getNombre1()
					+ "%");
		}
		if (!criteria.getPrimerApellido().equalsIgnoreCase("")) {
			query.append(" AND UPPER(BEN.PRIMER_APELLIDO||' '||BEN.SEGUNDO_APELLIDO) like UPPER(:PRIMER_APELLIDO) ");
			namedParameters.put("PRIMER_APELLIDO",
					"%" + criteria.getPrimerApellido() + "%");
		}
		if (criteria.getGrupoFamiliar() != null
				&& !criteria.getGrupoFamiliar().equalsIgnoreCase("")) {
			query.append(" AND UPPER(GF.NOMBRE) LIKE UPPER(:GF.NOMBRE) ");
			namedParameters.put("GF.NOMBRE", "%" + criteria.getGrupoFamiliar()
					+ "%");
		}

		List<BeneficiarioVO> cabezas = getNamedParameterJdbcTemplate().query(
				query.toString(), namedParameters,
				new RowMapper<BeneficiarioVO>() {
					public BeneficiarioVO mapRow(ResultSet rs, int rowNum)
							throws SQLException {
						BeneficiarioVO vo = new BeneficiarioVO();
						vo.setCode(new Long(rs.getLong("COD_CABEZA")));
						vo.setTipoDocumento(rs.getString("TIPO_DOCUMENTO"));
						vo.setNumeroDocumento(rs.getString("NUMERO_DOCUMENTO"));
						vo.setNombre1(rs.getString("PRIMER_NOMBRE"));
						vo.setNombre2(rs.getString("SEGUNDO_NOMBRE"));
						vo.setPrimerApellido(rs.getString("PRIMER_APELLIDO"));
						vo.setSegundoApellido(rs.getString("SEGUNDO_APELLIDO"));
						vo.setGrupoFamiliarCode(rs.getLong("COD_GF"));
						vo.setGrupoFamiliar(rs.getString("NOM_GF"));
						return vo;
					}
				});
		return cabezas;
	}

	public Collection<BeneficiarioVO> findGrupoFamiliar(BeneficiarioVO criteria) {
		Map<String, Object> namedParameters = new HashMap<String, Object>();

		// ArrayList<BeneficiarioVO> beneficiarios = new
		// ArrayList<BeneficiarioVO>();
		List<BeneficiarioVO> beneficiarios = new ArrayList<BeneficiarioVO>();
		if (criteria.getGrupoFamiliarCode() != null) {
			namedParameters.put("gf_codigo", criteria.getGrupoFamiliarCode());
			beneficiarios = getNamedParameterJdbcTemplate().query(FIND_GF,
					namedParameters, new RowMapper<BeneficiarioVO>() {
						public BeneficiarioVO mapRow(ResultSet rs, int rowNum)
								throws SQLException {
							BeneficiarioVO vo = new BeneficiarioVO();
							vo.setCode(new Long(rs.getLong("CODIGOBENE")));
							vo.setNumeroDocumento(rs
									.getString("NUMERO_DOCUMENTO"));
							vo.setNombre1(rs.getString("PRIMER_NOMBRE"));
							vo.setNombre2(rs.getString("SEGUNDO_NOMBRE"));
							vo.setPrimerApellido(rs
									.getString("PRIMER_APELLIDO"));
							vo.setSegundoApellido(rs
									.getString("SEGUNDO_APELLIDO"));
							vo.setGrupoFamiliar(rs.getString("Nombre_Grupo"));
							vo.setParentesco(rs.getString("PARENTESCO"));
							vo.setPoseeBeneficios(findCountBeneficios(rs
									.getLong("CODIGOBENE")));
							vo.setCodeCabezaGF(new Long(rs
									.getLong("COD_CABEZA")));
							vo.setNombreCabezaGF(rs.getString("NOMBRE_CABEZA"));
							vo.setDocumentoCabezaGF(rs.getString("DOC_CABEZA"));
							return vo;
						}
					});
		}
		return beneficiarios;
	}

	public String findEdad(Long codeBeneficiario) {
		Map<String, Object> namedParameters = new HashMap<String, Object>();

		namedParameters.put("CODIGO", codeBeneficiario.longValue());
		return getNamedParameterJdbcTemplate().queryForObject(
				SELECT_EDAD_BENEFICIARIO_BY_CODIGO, namedParameters,
				String.class);
	}

	public String[] insert(BeneficiarioVO criteria) {
		Map<String, Object> namedParameters = new HashMap<String, Object>();

		int numRows = 0;

		// convertir el sexo de convencion sisben a sub. (si es
		// 1->'M', si es 2-> 'F')
		Utility.formatSisbenSex(criteria);
		// criteria.setSexo(criteria.getSexo().equals("1") ? "M" : "F");
		// test fsr. convertir tipo_documento a convencion sub. en sisben hay
		// 0,1,2,3,4
		criteria.setTipoDocumento(Utility
				.deformatSisbenDocumentToSubDocument(criteria
						.getTipoDocumento()));

		namedParameters.put("NUMERO_DOCUMENTO", criteria.getNumeroDocumento()
				.trim());
		namedParameters.put("TIPO_DOCUMENTO", criteria.getTipoDocumento());
		namedParameters.put("PRIMER_NOMBRE", criteria.getNombre1().trim());
		namedParameters.put("SEGUNDO_NOMBRE", criteria.getNombre2().trim());
		namedParameters.put("PRIMER_APELLIDO", criteria.getPrimerApellido()
				.trim());
		namedParameters.put("SEGUNDO_APELLIDO", criteria.getSegundoApellido()
				.trim());
		namedParameters.put("VFL_CODIGO_COMUNA", criteria.getVflComuna());
		namedParameters.put("FECHA_NACIMIENTO", criteria.getFechaNacimiento());
		namedParameters.put("SEXO", criteria.getSexo());
		namedParameters.put("TELEFONO", criteria.getTelefono());
		namedParameters.put("DIRECCION_DESCRIPTIVA",
				criteria.getDirDescriptiva());
		namedParameters.put("DIRECCION_ENCASILLADA",
				criteria.getDirEncasillada());
		namedParameters.put("LOCALIZACION_COBAMA", criteria.getCobama());
		namedParameters.put("VFL_CODIGO_BARRIO", criteria.getCodeBarrio());
		namedParameters.put("VFL_CODIGO_ZONA", criteria.getCodeZona());
		namedParameters.put("CORREO_ELECTRONICO", criteria.getMail());
		namedParameters.put("ETNIA", criteria.getEtnia());
		namedParameters.put("usuario_crea", criteria.getCreationUser());
		namedParameters.put("terminal_crea", criteria.getCreationTerminal());
		namedParameters.put("fecha_crea", criteria.getCreationDate());
		namedParameters.put("usuario_modifica", criteria.getUpdateUser());
		namedParameters.put("terminal_modifica", criteria.getUpdateTerminal());
		namedParameters.put("fecha_modifica", criteria.getUpdateDate());
		namedParameters.put("HECHO_VICTIMIZANTE",
				criteria.getHechoVictimizante());

		GeneratedKeyHolder generatedKeyHolder = new GeneratedKeyHolder();
		SqlParameterSource parameterSource = new MapSqlParameterSource(
				namedParameters);
		numRows = getNamedParameterJdbcTemplate().update(INSERT_BENEFICIARIO,
				parameterSource, generatedKeyHolder, new String[] { "CODIGO" });

		if (numRows == 0) {
			throw new DAOException("No se ha ingresado el registro.");
		}

		Long code;
		code = generatedKeyHolder.getKey().longValue();

		String retorno[] = new String[2];
		if (numRows > 0) {
			retorno[0] = "true";
			retorno[1] = code.toString();
			return retorno;
		} else {
			retorno[0] = "false";
			retorno[1] = code.toString();
			return retorno;
		}
	}

	public Collection<BeneficioVO> findBeneficiosByCodBen(Long codeBeneficiario) {
		Map<String, Object> namedParameters = new HashMap<String, Object>();

		namedParameters.put("CODBEN", codeBeneficiario);
		List<BeneficioVO> beneficios = getNamedParameterJdbcTemplate().query(
				FIND_BENEFICIOS_BY_CODBEN, namedParameters,
				new RowMapper<BeneficioVO>() {
					public BeneficioVO mapRow(ResultSet rs, int rowNum)
							throws SQLException {
						BeneficioVO vo = new BeneficioVO();
						vo.setCode(rs.getLong("CODSUBPROG"));
						vo.setNombre(rs.getString("NOMSUBPROG"));
						vo.setFecha(rs.getString("FECHA"));
						vo.setCodSede(rs.getLong("CODSEDE"));
						vo.setNomSede(rs.getString("NOMSEDE"));
						vo.setCodPrograma(rs.getLong("CODPROG"));
						vo.setNomPrograma(rs.getString("NOMPROG"));
						vo.setCodCategoria(rs.getLong("CODCATEGORIA"));
						vo.setNomCategoria(rs.getString("NOMCATEGORIA"));
						vo.setRenovar(rs.getString("RENOVAR"));
						vo.setDiasReutilizar(rs.getString("DIASREUTILIZAR"));
						vo.setCodeBot(rs.getLong("CODBOT"));
						return vo;
					}
				});
		return beneficios;
	}

	public Collection<BeneficioVO> findUltimosBeneficios(Long codeBeneficiario) {
		Map<String, Object> namedParameters = new HashMap<String, Object>();

		List<BeneficioVO> beneficios = new ArrayList<BeneficioVO>();

		int iTotal = 0;
		int iCount = 0;
		int valor = 0;

		namedParameters.put("BEN_CODIGO", codeBeneficiario);
		List<Map<String, Object>> rows = getNamedParameterJdbcTemplate()
				.queryForList(FIND_ULTIMOS_BENEFICIOS, namedParameters);
		for (Map<String, Object> row : rows) {
			BeneficioVO vo = new BeneficioVO();
			BigDecimal code = (BigDecimal) row.get("CODSUBPROG");
			if (code != null) {
				vo.setCode(code.longValueExact());
			}
			vo.setNombre((String) row.get("NOMSUBPROG"));
			vo.setFecha((String) row.get("FECHA"));
			BigDecimal codeSede = (BigDecimal) row.get("CODSEDE");
			if (codeSede != null) {
				vo.setCodSede(codeSede.longValueExact());
			}
			vo.setNomSede((String) row.get("NOMSEDE"));
			BigDecimal codeProg = (BigDecimal) row.get("CODPROG");
			if (codeProg != null) {
				vo.setCodPrograma(codeProg.longValueExact());
			}
			vo.setNomPrograma((String) row.get("NOMPROG"));
			BigDecimal codeCateg = (BigDecimal) row.get("CODCATEGORIA");
			if (codeCateg != null) {
				vo.setCodCategoria(codeCateg.longValueExact());
			}
			vo.setNomCategoria((String) row.get("NOMCATEGORIA"));
			vo.setRenovar((String) row.get("RENOVAR"));
			BigDecimal diasReutilizar = (BigDecimal) row.get("DIASREUTILIZAR");
			vo.setDiasReutilizar(diasReutilizar.toString());
			BigDecimal codeBot = (BigDecimal) row.get("CODBOT");
			if (codeBot != null) {
				vo.setCodeBot(codeBot.longValueExact());
			}
			BigDecimal codeArea = (BigDecimal) row.get("CODAREA");
			if (codeArea != null) {
				vo.setCodeArea(codeArea.longValueExact());
			}
			vo.setNomArea((String) row.get("NOMAREA"));
			BigDecimal valorBen = (BigDecimal) row.get("ValorBen");
			if (valorBen != null) {
				vo.setValor(valorBen.intValueExact());
				valor += valorBen.intValueExact();
			}

			BigDecimal codeSubprog = (BigDecimal) row.get("CODSUBPROG");
			BigDecimal codBen = (BigDecimal) row.get("CODBEN");
			iCount = findCountBeneficios(codeSubprog.longValueExact(),
					(codBen.longValueExact()));
			iTotal += iCount;
			vo.setNumeroBeneficios(iCount);
			beneficios.add(vo);
		}

		if (beneficios != null && beneficios.size() > 0) {
			BeneficioVO vo = new BeneficioVO();
			vo.setCode(new Long("0"));
			vo.setNombre("");
			vo.setFecha("");
			vo.setCodSede(new Long("0"));
			vo.setNomSede("");
			vo.setCodPrograma(new Long("0"));
			vo.setNomPrograma("");
			vo.setCodCategoria(new Long("0"));
			vo.setNomCategoria("");
			vo.setRenovar("");
			vo.setDiasReutilizar("");
			vo.setCodeBot(new Long("0"));
			vo.setCodeArea(new Long("0"));
			vo.setNomArea("TOTAL");
			vo.setNumeroBeneficios(iTotal);
			vo.setValor(valor);
			beneficios.add(vo);
		}
		return beneficios;
	}

	public boolean delete(Long codeBeneficiario, String user, String terminal,
			String fecha) {
		Map<String, Object> namedParameters = new HashMap<String, Object>();

		String query = "UPDATE TCS_BEN_BENEFICIARIO SET CAMPO_A1 = 'S', "
				+ " usuario_modifica = :usuario_modifica, terminal_modifica = :terminal_modifica, "
				+ " fecha_modifica = TO_DATE(:fecha_modifica,'dd/mm/rrrr') "
				+ " WHERE CODIGO = :CODIGO ";
		int iregAfect = 0;

		namedParameters.put("usuario_modifica", user);
		namedParameters.put("terminal_modifica", "WEB=" + terminal);
		namedParameters.put("fecha_modifica", fecha);
		namedParameters.put("CODIGO", codeBeneficiario);
		iregAfect = getNamedParameterJdbcTemplate().update(query,
				namedParameters);
		if (iregAfect > 0) {
			return true;
		} else {
			return false;
		}
	}

	public boolean deleteBeneficio(Long codeBeneficiario, Long codeBeneficio,
			String user, String terminal, String fecha) {
		Map<String, Object> namedParameters = new HashMap<String, Object>();

		boolean retorno = false;
		if (codeBeneficiario != null && codeBeneficio != null) {
			String query = "SELECT codigo FROM TCS_BEN_BENEFICIO_OTORGADO WHERE SBPR_CODIGO = :SBPR_CODIGO AND BEN_CODIGO = :BEN_CODIGO ";

			namedParameters.put("SBPR_CODIGO", codeBeneficio);
			namedParameters.put("BEN_CODIGO", codeBeneficiario);

			int iReg = 0;
			List<Map<String, Object>> rows = getNamedParameterJdbcTemplate()
					.queryForList(query, namedParameters);
			// reusar
			namedParameters.clear();
			for (Map<String, Object> row : rows) {
				retorno = true;
				Long codigo = (Long) row.get("codigo");
				query = "UPDATE TCS_BEN_BENEFICIO_OTORGADO SET campo_a1 = 'E', "
						+ " usuario_modifica = :usuario_modifica, terminal_modifica = :terminal_modifica, "
						+ " fecha_modifica = TO_DATE(:fecha_modifica,'dd/mm/rrrr') "
						+ " WHERE codigo = :codigo ";

				namedParameters.put("usuario_modifica", user);
				namedParameters.put("terminal_modifica", "WEB=" + terminal);
				namedParameters.put("fecha_modifica", fecha);
				namedParameters.put("codigo", codigo);

				iReg = getNamedParameterJdbcTemplate().update(query,
						namedParameters);
				if (iReg == 0) {
					throw new DAOException("No se actualizo el registro.");
				} else if (iReg > 1) {
					throw new DAOException(
							"Se iba a actualizar mas de un registro. Se revierte la operacion.");
				}
			}
		}
		return retorno;
	}

	public boolean isBeneficiarioAsignadoAGrupoFamiliar(
			Long codigoBeneficiario, Long codigoGrupoFamiliar) {
		Map<String, Object> namedParameters = new HashMap<String, Object>();

		namedParameters.put("BEN_CODIGO", codigoBeneficiario);
		namedParameters.put("GF_CODIGO", codigoGrupoFamiliar);
		try {
			Long code = getNamedParameterJdbcTemplate().queryForObject(
					IS_BENEFICIARIO_ASIGNADO, namedParameters, Long.class);
			return true;
		} catch (IncorrectResultSizeDataAccessException e) {
			return false;
		}

	}

	public boolean isBeneficiarioSubprograma(Long codeBeneficiario,
			Long codeSubprograma) {
		Map<String, Object> namedParameters = new HashMap<String, Object>();

		namedParameters.put("CODBEN", codeBeneficiario);
		namedParameters.put("CODSUBPROG", codeSubprograma);
		List<Map<String, Object>> rows = getNamedParameterJdbcTemplate()
				.queryForList(SELECT_ALL_VCS_BEN_OTOR_BY_CODBEN_CODSUBPROG,
						namedParameters);
		if (rows != null) {
			if (rows.size() > 0) {
				return true;
			}
		}
		return false;
	}

	public Long findCodeBeneficiarioByCodeBOT(Long codeBOT) {
		Map<String, Object> namedParameters = new HashMap<String, Object>();

		namedParameters.put("codigo", codeBOT);
		try {
			return getNamedParameterJdbcTemplate().queryForObject(
					SELECT_BEN_CODIGO, namedParameters, Long.class);
		} catch (IncorrectResultSizeDataAccessException e) {
			return null;
		}
	}

	private String findPoseeBeneficios(Long codeBeneficiario)
			throws SQLException {
		Map<String, Object> namedParameters = new HashMap<String, Object>();

		String query = "SELECT CODSUBPROG FROM VCS_BENEFICIOS_OTORGADOS "
				+ "WHERE CODBEN = :CODBEN ";

		namedParameters.put("CODBEN", codeBeneficiario);
		List<Map<String, Object>> res = getNamedParameterJdbcTemplate()
				.queryForList(query, namedParameters);
		if (res.size() > 0) {
			return "Si";
		} else {
			return "No";
		}
	}

	/**
	 * Metodo para obtener el numero de beneficios Otorgados
	 * 
	 * @param code
	 * @return
	 * @throws java.sql.SQLException
	 */
	private String findCountBeneficios(Long code) {
		Map<String, Object> namedParameters = new HashMap<String, Object>();

		String query = "SELECT COUNT(1) NUMBENE FROM (SELECT SBPR_CODIGO, BEN_CODIGO "
				+ " FROM BENEFICIOS.TCS_BEN_BENEFICIO_OTORGADO beneotorg "
				+ " WHERE TO_DATE(beneotorg.FECHA_BENEFICIO,'dd/mm/rrrr') <= TO_DATE(sysdate,'dd/mm/rrrr') "
				+ " AND beneotorg.BEN_CODIGO = :BEN_CODIGO )";

		namedParameters.put("BEN_CODIGO", code.longValue());
		try {
			int contador = getNamedParameterJdbcTemplate().queryForObject(
					query, namedParameters, Integer.class);
			return String.valueOf(contador);
		} catch (IncorrectResultSizeDataAccessException e) {
			return String.valueOf(0);
		}
	}

	public int findCountBeneficios(Long codeSubprograma, Long codeBeneficiario) {
		Map<String, Object> namedParameters = new HashMap<String, Object>();

		String strSql = "SELECT COUNT(1) total "
				+ " FROM tcs_ben_beneficio_otorgado bot "
				+ " WHERE TO_DATE(bot.FECHA_BENEFICIO,'dd/mm/rrrr') <= TO_DATE(sysdate,'dd/mm/rrrr') "
				+ " AND bot.BEN_CODIGO = :BEN_CODIGO AND bot.SBPR_CODIGO = :SBPR_CODIGO ";

		namedParameters.put("BEN_CODIGO", codeBeneficiario);
		namedParameters.put("SBPR_CODIGO", codeSubprograma);

		try {
			int count = getNamedParameterJdbcTemplate().queryForObject(strSql,
					namedParameters, Integer.class);
			return count;
		} catch (IncorrectResultSizeDataAccessException e) {
			return 0;
		}
	}

}
